//
// Created by fh on 2021/6/2.
//

#include "SqQueue.h"

/* 初始化一个空队列 */
Status SqQueueInitQueue(SqQueue *q) {
    if (q == NULL) {
        return ERROR;
    }
    q->front = 0;
    q->rear = 0;
    return OK;
}

/* 返回q的元素个数，也就是队列的当前长度 */
int SqQueueQueueLength(SqQueue q) {
    int result = 0;
    result = (q.rear - q.front + MAXSIZE) % MAXSIZE;
    return result;
}

/* 若队列未满，则插入元素e为q新的队尾元素 */
Status SqQueueEnQueue(SqQueue *q,int e) {
    if ((q->rear + 1) % MAXSIZE == q->front) {
        printf("循环队列已满\n");
        return ERROR; /* 队列满的判断 */
    }
    q->data[q->rear] = e;
    // 这里不能单纯用q->rear++来修改尾指针,因为有可能溢出数组
    q->rear = (q->rear + 1) % MAXSIZE;
    return OK;
}

/* 若队列不空,则删除q中队头元素,用e返回其值 */
Status SqQueueDeQueue(SqQueue *q,int *e) {
    if (q->front == q->rear) {
        printf("循环队列是空的\n");
        return ERROR; /* 队列空的判断 */
    }
    *e = q->data[q->front];
    q->data[q->front] = 0; /* 这里可以不处理，不处理内存里会残留以前的值 */
    q->front = (q->front + 1) % MAXSIZE;
    return OK;
}

/* 遍历循环队列 */
Status SqQueueDisplay(SqQueue q) {
    printf("front:%d  rear:%d\n",q.front,q.rear);
    if (q.front == q.rear) {
        printf("空队列\n");
        return ERROR;
    }
    printf("遍历顺序循环队列: ");
    /*
    if (q.front < q.rear) {
        for (int i = q.front; i < q.rear; ++i) {
            printf("%d ",q.data[i]);
        }
    } else {
        for (int i = q.front; i < MAXSIZE; ++i) {
            printf("%d ",q.data[i]);
        }
        for (int i = 0; i < q.rear; ++i) {
            printf("%d ",q.data[i]);
        }
    }
    //*/
    //*
    for (int i = q.front; i != q.rear; ) {
        printf("%d ",q.data[i]);
        i = (i + 1) % MAXSIZE;
    }
    //*/
    printf("\n");
    printf("整个数组内存遍历: ");
    for (int i = 0; i < MAXSIZE; ++i) {
        printf("%d ",q.data[i]);
    }
    printf("\n");
    return OK;
}

/* 测试demo */
void sqQueueTestDemo() {
    {
        SqQueue *q = (SqQueue *) malloc(sizeof(SqQueue));

        printf("--------------------------- 顺序循环队列初始化 ------------------------\n");
        Status result = SqQueueInitQueue(q);
        printf("SqQueueInitQueue result: %d\n",result);
        SqQueueDisplay(*q);

        printf("--------------------------- 顺序循环队列进队 ------------------------\n");
        result = SqQueueEnQueue(q,32);
        printf("SqQueueEnQueue result: %d\n",result);
        SqQueueDisplay(*q);

        result = SqQueueEnQueue(q,12);
        printf("SqQueueEnQueue result: %d\n",result);
        SqQueueDisplay(*q);

        result = SqQueueEnQueue(q,89);
        printf("SqQueueEnQueue result: %d\n",result);
        SqQueueDisplay(*q);

        result = SqQueueEnQueue(q,5);
        printf("SqQueueEnQueue result: %d\n",result);
        SqQueueDisplay(*q);

        result = SqQueueEnQueue(q,56);
        printf("SqQueueEnQueue result: %d\n",result);
        SqQueueDisplay(*q);

        printf("--------------------------- 顺序循环队列出队 ------------------------\n");
        int a = 0;
        result = SqQueueDeQueue(q,&a);
        printf("SqQueueDeQueue result: %d\n",result);
        printf("a: %d\n",a);
        SqQueueDisplay(*q);

        result = SqQueueEnQueue(q,56);
        printf("SqQueueEnQueue result: %d\n",result);
        SqQueueDisplay(*q);

        a = 0;
        result = SqQueueDeQueue(q,&a);
        printf("SqQueueDeQueue result: %d\n",result);
        printf("a: %d\n",a);
        SqQueueDisplay(*q);

        a = 0;
        result = SqQueueDeQueue(q,&a);
        printf("SqQueueDeQueue result: %d\n",result);
        printf("a: %d\n",a);
        SqQueueDisplay(*q);

    }
}


